// Copyright (c) 2005  INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of cgal-python; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; version 2.1 of the License.
// See the file LICENSE.LGPL distributed with cgal-python.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $Id: Py_Segment_3.cpp 167 2007-11-02 15:36:54Z spion $
// $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal-python/trunk/cgal-python/bindings/Kernel/Py_Segment_3.cpp $
//
// Author(s)     : Naceur Meskini
//=========================================================================

#include <CGAL/basic.h>
#include <include/Kernels.h>

#include <boost/python.hpp>
#include <boost/cstdint.hpp>

const char* Segment_3_doc[] =
{
"An object s of the data type Segment_3 is a directed straight line segment in the three-dimensional Euclidean space\n\
i.e. a straight line segment [p,q] connecting two points p,q The segment is topologically closed, i.e.\n\
the end points belong to it. Point p is called the source and q is called the target of s. \n\
The length of s is the Euclidean distance between p and q.\n\
Note that there is only a function to compute the square of the length, because otherwise we had to perform a square \n\
root operation which is not defined for all number types, which is expensive, and may not be exact.\n\
For more details see a C++ doc:\n\
http://www.cgal.org/Manual/3.2/doc_html/cgal_manual/Kernel_23_ref/Class_Segment_3.html",

"s = Segment_3( Point_3 p, Point_3 q)\nintroduces a segment s with source p and target q.\n The segment is directed from the source towards the target.\n",
"source(self) -> Point_3\nreturns the source of s.\n",

"target(self) -> Point_3\nreturns the target of s.\n",

"min(self) ->  Point_3\nreturns the point of s with lexicographically smallest coordinate.\n",

"max(self) ->  Point_3\nreturns the point of Segment with lexicographically largest coordinate.\n",

"vertex(self,i) -> Point_3\nreturns source or target of s: vertex(0) returns the source of s, vertex(1) returns the target of s.\nThe parameter i is taken modulo 2, which gives easy access to the other vertex.\n",

"point(self,int i) -> returns vertex(i).\n",

"has_on(self,Point_3 p) -> bool\nA point p is on s, iff it is equal to the source or target of s, or if it is in the interior of s.\n",

"", // "collinear_has_on(self,Point_3) -> bool\nchecks if point p is on segment s. This function is faster than function has_on().\nPrecondition: p is on the supporting line of s.", // not in CGAL 3.3 anymore, and was not documented in 3.x.

"squared_length(self) -> double\nreturns the squared length of s.",

"is_degenerate(self) -> bool\nsegment s is degenerate, if source and target are equal. \n",

"bbox(self) -> Bbox_3\nreturns a bounding box containing s.\n",

"to_vector(self) -> Vector_3\nreturns the vector s.target() - s.source(). \n",

"supporting_line(self) -> Line_3\nreturns the line l passing through s.\nLine l has the same orientation as segment s.\n",

"opposite(self) -> Segment_3\nreturns a segment with source and target point interchanged.\n",

"transform(self,Aff_transformation_3 t) -> Segment_3\nreturns the segment obtained by applying t on the source and the target of s.\n",

"direction(self) -> Direction_3\nreturns the direction from source to target of s.\n",

"s[i] -> Point_3\nreturns vertex(i)\n"
};

template<class Segment_3>
boost::python::str py_repr_Segment_3(const Segment_3& s )
{
	using namespace boost::python;
	return str("Segment_3("+ str(s.source()) +","+ str(s.target()) +")" );
}

template <class kernel > 
void Py_Segment_3()
{
	typedef typename kernel::Point_3 							Point_3;
	typedef typename kernel::Segment_3 							Segment_3;

	using namespace boost::python;

        class_< Segment_3 >("Segment_3", Segment_3_doc[0],init<>())
        .def(init< const Segment_3& >(Segment_3_doc[1]))
        .def(init< const Point_3&, const Point_3& >())
        .def("source", &Segment_3::source, BEF_33(by_cref, by_copy)(), Segment_3_doc[2])
        .def("target", &Segment_3::target, BEF_33(by_cref, by_copy)(), Segment_3_doc[3])
        .def("min", &Segment_3::min, BEF_33(by_cref, by_copy)(), Segment_3_doc[4])
        .def("max", &Segment_3::max, BEF_33(by_cref, by_copy)(), Segment_3_doc[5])
        .def("vertex", &Segment_3::vertex, BEF_33(by_cref, by_copy)(), Segment_3_doc[6])
        .def("point", &Segment_3::point, BEF_33(by_cref, by_copy)(), Segment_3_doc[7])
        .def("has_on", &Segment_3::has_on, Segment_3_doc[8])
        //.def("collinear_has_on", &Segment_3::collinear_has_on, Segment_3_doc[9])
        .def("squared_length", &Segment_3::squared_length, Segment_3_doc[10])
        .def("is_degenerate", &Segment_3::is_degenerate, Segment_3_doc[11])
        .def("bbox", &Segment_3::bbox, Segment_3_doc[12])
        .def("to_vector", &Segment_3::to_vector, Segment_3_doc[13])
        .def("supporting_line", &Segment_3::supporting_line, Segment_3_doc[14])
        .def("opposite", &Segment_3::opposite, Segment_3_doc[15])
        .def("transform", &Segment_3::transform, Segment_3_doc[16])
        .def("direction", &Segment_3::direction, Segment_3_doc[17])
        .def("__getitem__", &Segment_3::operator [], BEF_33(by_cref, by_copy)(), Segment_3_doc[18])
        .def("__repr__", &py_repr_Segment_3<Segment_3>)

        .def( self == self )
        .def( self != self )
    ;
}

void export_Segment_3()
{
	Py_Segment_3<K>();
}
